from pydantic import BaseModel
from typing import Optional, List, Generic, TypeVar
from datetime import date, datetime
from sqlalchemy import Column, Integer, String, Float, Date, DateTime
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

T = TypeVar('T')

class InvoiceBase(BaseModel):
    invoice_code: str
    invoice_number: str
    issue_date: date
    buyer_name: str
    buyer_tax_id: str
    buyer_address: Optional[str] = None
    buyer_phone: Optional[str] = None
    buyer_bank: Optional[str] = None
    buyer_account: Optional[str] = None
    seller_name: str
    seller_tax_id: str
    seller_address: Optional[str] = None
    seller_phone: Optional[str] = None
    seller_bank: Optional[str] = None
    seller_account: Optional[str] = None
    item_name: Optional[str] = None
    license_plate: Optional[str] = None
    vehicle_type: Optional[str] = None
    pass_start_date: Optional[date] = None
    pass_end_date: Optional[date] = None
    amount: float
    tax_rate: float
    tax_amount: float
    total_price: float
    remarks: Optional[str] = None
    payee: Optional[str] = None
    reviewer: Optional[str] = None
    issuer: str
    source_file_path: Optional[str] = None

class InvoiceCreate(InvoiceBase):
    pass

class InvoiceResponse(InvoiceBase):
    id: int
    created_at: datetime
    updated_at: datetime

    class Config:
        orm_mode = True

class Invoice(Base):
    __tablename__ = "invoice"

    id = Column(Integer, primary_key=True, index=True)
    invoice_code = Column(String)
    invoice_number = Column(String)
    issue_date = Column(Date)
    buyer_name = Column(String)
    buyer_tax_id = Column(String)
    buyer_address = Column(String, nullable=True)
    buyer_phone = Column(String, nullable=True)
    buyer_bank = Column(String, nullable=True)
    buyer_account = Column(String, nullable=True)
    seller_name = Column(String)
    seller_tax_id = Column(String)
    seller_address = Column(String, nullable=True)
    seller_phone = Column(String, nullable=True)
    seller_bank = Column(String, nullable=True)
    seller_account = Column(String, nullable=True)
    item_name = Column(String, nullable=True)
    license_plate = Column(String, nullable=True)
    vehicle_type = Column(String, nullable=True)
    pass_start_date = Column(Date, nullable=True)
    pass_end_date = Column(Date, nullable=True)
    amount = Column(Float)
    tax_rate = Column(Float)
    tax_amount = Column(Float)
    total_price = Column(Float)
    remarks = Column(String, nullable=True)
    payee = Column(String, nullable=True)
    reviewer = Column(String, nullable=True)
    issuer = Column(String)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    source_file_path = Column(String, nullable=True)

class PaginatedResponse(BaseModel, Generic[T]):
    data: List[T]
    total: int
    page: int
    limit: int
    totalPages: int